package com.bolingcavalry.crm.summaryorder.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.base.PageResult;
import com.base.ResponseResult;

import com.base.RoleEnum;
import com.base.Status;
import com.bolingcavalry.crm.aftersales.mapper.AfterSalesMapper;
import com.bolingcavalry.crm.message.config.RabbitMQConstants;
import com.bolingcavalry.crm.receiver.mapper.ReceiverMapper;
import com.bolingcavalry.crm.security.utils.SecurityUtils;
import com.bolingcavalry.crm.serviceorder.mapper.ServiceOrderMapper;
import com.bolingcavalry.crm.summaryorder.mapper.ServiceSummaryOrderMapper;
import com.bolingcavalry.crm.summaryorder.service.ServiceSummaryOrderService;
import com.bolingcavalry.crm.utils.AUtils;
import com.dto.ServiceSummaryOrderDTO;
import com.dto.TaskReviewMessageDTO;
import com.dto.servicesummary.ServiceSummaryStatusDTO;
import com.entity.aftersales.AfterSales;
import com.entity.receiver.Receiver;
import com.entity.serviceorder.ServiceOrder;
import com.entity.summaryorder.ServiceSummaryOrder;
import com.vo.ServiceSummaryOrderVO;
import io.swagger.annotations.Api;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;


@Api("服务总结单管理")
@RestController
@RequestMapping("/summary")
@Slf4j
public class ServiceSummaryOrderController {

    @Autowired
    private ServiceSummaryOrderService serviceSummaryOrderService;
    @Autowired
    private AUtils aUtils;
    @Autowired
    private ReceiverMapper receiverMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ServiceOrderMapper serviceOrderMapper;
    @Autowired
    private ServiceSummaryOrderMapper serviceSummaryOrderMapper;
    @Autowired
    private AfterSalesMapper afterSalesMapper;


    /**
     * 新增服务总结单
     */
    @PostMapping("/add")
    public ResponseResult add(@RequestBody ServiceSummaryOrderDTO order) {
        return serviceSummaryOrderService.save(order);
    }
    /**
     * 上传总结单并归档
     */
    @GetMapping("/updateByImage")
    public ResponseResult updateByImage(@RequestParam("image") MultipartFile image) throws Exception {
        ServiceSummaryOrderVO serviceSummaryOrderVO = serviceSummaryOrderService.updateByImage(image);
        return ResponseResult.success("归档成功", serviceSummaryOrderVO);
    }

    /**
     * 修改服务总结单
     */
    @PostMapping("/update")
    public ResponseResult update(@RequestBody ServiceSummaryOrderDTO order) {
        return serviceSummaryOrderService.update(order);
    }

    /**
     * 删除服务总结单（逻辑删除）
     */
    @DeleteMapping("/delete")
    public ResponseResult delete(@RequestBody String[] ids) {
        serviceSummaryOrderService.batchDelete(ids);
        return ResponseResult.success("批量逻辑删除成功");
    }

    /**
     * 查询服务总结单详情
     */
    @GetMapping("/get/{id}")
    public ResponseResult<ServiceSummaryOrderVO> getById(@PathVariable Long id) {
        ServiceSummaryOrderVO order = serviceSummaryOrderService.getById(id);
        return ResponseResult.success("查询成功", order);
    }

    /**
     * 根据售后编号查询服务总结单详细
     */
    @GetMapping("/getByServiceNumber/{orderNumber}")
    public ResponseResult<ServiceSummaryOrderVO> getByServiceNumber(@PathVariable String orderNumber) {
        ServiceSummaryOrderVO order = serviceSummaryOrderService.getByServiceNumber(orderNumber);
        return ResponseResult.success("查询成功", order);
    }


    /**
     * 分页查询服务总结单
     */
    @GetMapping("/list")
    public ResponseResult<PageResult<ServiceSummaryOrder>> list(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(required = false) Integer pageSize,
            //服务编号
            @RequestParam(required = false) String serviceNumber,
            //客户公司
            @RequestParam(required = false) String customerCompany,
            //销售经理
            @RequestParam(required = false) String salesManager,
            //开始时间
            @RequestParam(required = false) String startDate,
            //结束时间
            @RequestParam(required = false) String endDate
            )
    {
        IPage<ServiceSummaryOrderVO> page = serviceSummaryOrderService.getByPage(pageNum, pageSize, serviceNumber, customerCompany, salesManager, startDate, endDate);
        PageResult<ServiceSummaryOrderVO> result = new PageResult<>();
        result.setTotal(page.getTotal());
        result.setPages((int) page.getPages());
        result.setCurrent((int) page.getCurrent());
        result.setSize(pageSize);
        result.setRecords(page.getRecords());
        return ResponseResult.success("分页查询成功", result);
    }

    /**
     * 修改总结单状态订单流转
     * 总结单完结
     * 工单状态更新，状态为由进行中改为完结态
     * 完结需要通知技术指挥部，综合部，部门负责人，销售经理
     * 总结单状态（编辑，确认，完结）
     * 状态流转：编辑-确认-->下推到负责人手中-待完结审核-完结
     */
     @PostMapping("/updateStatus")
     public ResponseResult updateStatus(@RequestBody ServiceSummaryStatusDTO summaryOrderDTO) {
         //根据id查询总结单
         Long id = summaryOrderDTO.getId();
         String status = summaryOrderDTO.getStatus();
         ServiceSummaryOrderVO serviceSummaryOrderVO = serviceSummaryOrderService.getById(id);
         if(serviceSummaryOrderVO== null){
             return ResponseResult.error("未找到该服务总结单");
         }
         if(summaryOrderDTO.getStartTime()== null||summaryOrderDTO.getEndTime()==null){
             return ResponseResult.error("请选择开始时间和结束时间");
         }
         if(serviceSummaryOrderVO.getStatus().equals(Status.SERVICE_ORDER_STATUS_COMPLETED)){
             return ResponseResult.error("该服务总结单已完结，不允许修改");
         }
         if(serviceSummaryOrderVO.getStatus().equals(Status.SERVICE_ORDER_STATUS_COMPLETED_TO_BE_REVIEWED)){
             return ResponseResult.error("该服务总结单正在审核中，请勿重复操作");
         }
         //更新完结时间
         if(serviceSummaryOrderVO.getCompletionDate()==null || serviceSummaryOrderVO.getCompletionDate().isEmpty()){
             ServiceSummaryOrder serviceSummaryOrder = new ServiceSummaryOrder();
             serviceSummaryOrder.setId(id);
             serviceSummaryOrder.setCompletionDate(summaryOrderDTO.getEndTime().toLocalDate());
             serviceSummaryOrderMapper.updateById(serviceSummaryOrder);
         }
         //更新售后总括表的开始结束时间
         AfterSales afterSales = new AfterSales();
         LambdaUpdateWrapper<AfterSales> updateWrapper = new LambdaUpdateWrapper<>();
         updateWrapper.eq(AfterSales::getOrderNumber, serviceSummaryOrderVO.getServiceNumber());
         afterSales.setStartTime(summaryOrderDTO.getStartTime());
         afterSales.setEndTime(summaryOrderDTO.getEndTime());
         afterSales.setTravelExpense(summaryOrderDTO.getTravelExpense());
         //设置服务天数
         double v = calculateServiceDaysByBusinessRule(summaryOrderDTO.getStartTime(), summaryOrderDTO.getEndTime());
         afterSales.setServiceDays(v);

         afterSalesMapper.update(afterSales, updateWrapper);
         //获取任务接收人列表
         String serviceNumber = serviceSummaryOrderVO.getServiceNumber();
         LambdaQueryWrapper<Receiver> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(Receiver::getOrderNumber, serviceNumber);
         List<Receiver> receivers = receiverMapper.selectList(queryWrapper);
         //获取接收人名称
         List<String> receiverNames = receivers.stream().map(Receiver::getUserId).map(userId -> {
             //根据用户id获取用户名称
             return aUtils.getUserNickNameByUserId(userId);
         }).collect(Collectors.toList());
         //如果申请状态为完结
         TaskReviewMessageDTO taskReviewMessageDTO = new TaskReviewMessageDTO();
         //获取客户名称
         String companyName = serviceSummaryOrderVO.getCustomerCompanyName();
         taskReviewMessageDTO.setTitle("售后完结单"+serviceNumber+"审核通知");
         taskReviewMessageDTO.setContent("售后单编号："+serviceNumber+
                 "，客户名称："+companyName+
                 "，出行人员："+receiverNames);
         taskReviewMessageDTO.setBusinessType(Status.SUMMARY_ORDER);
         taskReviewMessageDTO.setOrderId(id);
         taskReviewMessageDTO.setOrderNumber(serviceNumber);
         taskReviewMessageDTO.setSenderName(SecurityUtils.getCurrentUsername());
         if(status.equals(Status.SERVICE_ORDER_STATUS_COMPLETED)) {
             //创建rabbitmq消息，因为要通知部门负责人，所以需要遍历该售后单的任务接收人？
             for (Receiver receiver : receivers) {
                 Long userId = receiver.getUserId();
                 //根据用户id获取角色列表，遍历列表设定taskReviewMessageDTO.getRoleName()
                 List<String> roleByUserId = aUtils.getRoleByUserId(userId);
                 String routingKey = null;
                 for (String s : roleByUserId) {
                     //生产
                     if (s.equals(RoleEnum.PRODUCTION_TECHNOLOGY.getCode())) {
                         //调用rabbitmq发送消息到消费者端
                         taskReviewMessageDTO.setRoleName(RoleEnum.PRODUCTION_LEADER.getCode());
                         routingKey=RabbitMQConstants.ROUTING_KEY_NOTIFY_COMMANDER;
                         // 创建rabbitmq消息，因为要通知部门负责人，所以需要遍历该售后单的任务接收人
                         rabbitTemplate.convertAndSend(
                                 RabbitMQConstants.EXCHANGE,
                                 routingKey,
                                 taskReviewMessageDTO
                         );
                     }
                     //综合
                     else if (s.equals(RoleEnum.GENERAL_DEPARTMENT.getCode())) {
                         taskReviewMessageDTO.setRoleName(RoleEnum.GENERAL_LEADER.getCode());
                         routingKey=RabbitMQConstants.ROUTING_KEY_NOTIFY_COMMANDER;
                         // 创建rabbitmq消息，因为要通知部门负责人，所以需要遍历该售后单的任务接收人
                         rabbitTemplate.convertAndSend(
                                 RabbitMQConstants.EXCHANGE,
                                 routingKey,
                                 taskReviewMessageDTO
                         );
                     }
                     //测控
                     else if (s.equals(RoleEnum.MC_DEPARTMENT.getCode())) {
                         taskReviewMessageDTO.setRoleName(RoleEnum.MC_LEADER.getCode());
                         routingKey=RabbitMQConstants.ROUTING_KEY_NOTIFY_COMMANDER;
                         // 创建rabbitmq消息，因为要通知部门负责人，所以需要遍历该售后单的任务接收人
                         rabbitTemplate.convertAndSend(
                                 RabbitMQConstants.EXCHANGE,
                                 routingKey,
                                 taskReviewMessageDTO
                         );
                     }
                     //销售
                     else if (s.equals(RoleEnum.SALES_DEPARTMENT.getCode())) {
                         taskReviewMessageDTO.setRoleName(RoleEnum.SALES_LEADER.getCode());
                         routingKey=RabbitMQConstants.ROUTING_KEY_NOTIFY_COMMANDER;
                         // 创建rabbitmq消息，因为要通知部门负责人，所以需要遍历该售后单的任务接收人
                         rabbitTemplate.convertAndSend(
                                 RabbitMQConstants.EXCHANGE,
                                 routingKey,
                                 taskReviewMessageDTO
                         );
                     }
                     //仪表
                     else if (s.equals(RoleEnum.INSTRUMENT_DEPARTMENT.getCode())) {
                         taskReviewMessageDTO.setRoleName(RoleEnum.INSTRUMENT_LEADER.getCode());
                         routingKey=RabbitMQConstants.ROUTING_KEY_NOTIFY_COMMANDER;
                         // 创建rabbitmq消息，因为要通知部门负责人，所以需要遍历该售后单的任务接收人
                         rabbitTemplate.convertAndSend(
                                 RabbitMQConstants.EXCHANGE,
                                 routingKey,
                                 taskReviewMessageDTO
                         );
                     }

                 }
             }
             //再去通知技术指挥部和综合部还有对应订单的销售经理
             taskReviewMessageDTO.setRoleName(RoleEnum.TECHNICAL_COMMAND.getCode());
             rabbitTemplate.convertAndSend(
                     RabbitMQConstants.EXCHANGE,
                     RabbitMQConstants.ROUTING_KEY_SUMMARY_ORDER,
                     taskReviewMessageDTO
             );
             //综合指挥部
             taskReviewMessageDTO.setRoleName(RoleEnum.GENERAL_COMMAND.getCode());
             rabbitTemplate.convertAndSend(
                     RabbitMQConstants.EXCHANGE,
                     RabbitMQConstants.ROUTING_KEY_SUMMARY_ORDER,
                     taskReviewMessageDTO
             );
             //对应的销售经理也就是具体的负责人id
             ServiceOrder serviceOrder = serviceOrderMapper.selectByOrderNumber(serviceNumber);
             if(serviceOrder.getSalesManagerId()!=null){
                 taskReviewMessageDTO.setReceiverId(serviceOrder.getSalesManagerId());
                 taskReviewMessageDTO.setRoleName(null);
                 rabbitTemplate.convertAndSend(
                         RabbitMQConstants.EXCHANGE,
                         RabbitMQConstants.ROUTING_KEY_NOTIFY_COMMANDER,
                         taskReviewMessageDTO
                 );
             }
         }
         serviceSummaryOrderService.updateStatus(id, Status.SERVICE_ORDER_STATUS_COMPLETED_TO_BE_REVIEWED);

         return ResponseResult.success("状态修改成功");
    }

    /**
     * 根据业务规则计算服务天数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 服务天数（可以是小数，0.5表示半天，1.0表示一天）
     */
    private double calculateServiceDaysByBusinessRule(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime.isAfter(endTime)) {
            throw new IllegalArgumentException("开始时间不能晚于结束时间");
        }

        double totalDays = 0.0;
        LocalDateTime current = startTime;

        while (current.isBefore(endTime)) {
            // 获取当天的日期
            LocalDate currentDate = current.toLocalDate();

            // 定义当天的关键时间点
            LocalDateTime dayStart = currentDate.atTime(8, 0);    // 8:00
            LocalDateTime noon = currentDate.atTime(12, 0);       // 12:00
            LocalDateTime evening = currentDate.atTime(18, 0);    // 18:00
            LocalDateTime nextDayStart = currentDate.plusDays(1).atTime(8, 0); // 第二天8:00

            // 如果当前时间早于当天8点，则从8点开始计算
            LocalDateTime actualStart = current.isBefore(dayStart) ? dayStart : current;

            // 确定今天的结束时间（取今天18点或实际结束时间的较小值）
            LocalDateTime dayEnd = endTime.isBefore(evening) ? endTime : evening;

            // 计算今天的工时
            if (actualStart.isBefore(dayEnd)) {
                // 在8:00-12:00之间
                LocalDateTime morningEnd = dayEnd.isBefore(noon) ? dayEnd : noon;
                if (actualStart.isBefore(morningEnd) && actualStart.isBefore(noon)) {
                    LocalDateTime segmentEnd = dayEnd.isBefore(noon) ? dayEnd : noon;
                    if (actualStart.isBefore(segmentEnd)) {
                        // 如果跨越了中午12点，则分段计算
                        if (actualStart.isBefore(noon) && segmentEnd.isAfter(noon)) {
                            // 上午部分
                            totalDays += 0.5;
                            // 下午部分继续计算
                            LocalDateTime afternoonStart = noon;
                            if (segmentEnd.isAfter(evening)) {
                                totalDays += 1.0; // 下午6点后算全天
                            } else if (segmentEnd.isAfter(noon)) {
                                totalDays += 0.5; // 12点到18点算半天
                            }
                        } else if (actualStart.isBefore(noon)) {
                            // 纯上午时间段
                            totalDays += 0.5;
                        } else if (actualStart.isBefore(evening)) {
                            // 纯下午时间段
                            if (segmentEnd.isAfter(evening)) {
                                totalDays += 1.0; // 下午6点后算全天
                            } else {
                                totalDays += 0.5; // 12点到18点算半天
                            }
                        }
                    }
                }

                // 如果结束时间超过了18:00，则剩余时间按整天计算
                if (dayEnd.isAfter(evening)) {
                    // 计算超过18点的部分按整天计算
                    long extraDays = java.time.temporal.ChronoUnit.DAYS.between(
                            dayEnd.toLocalDate(),
                            endTime.toLocalDate()
                    );
                    totalDays += extraDays;

                    // 再加上结束那天的时间
                    LocalDateTime endDayStart = endTime.toLocalDate().atTime(8, 0);
                    if (endTime.isAfter(endDayStart)) {
                        if (endTime.toLocalTime().isAfter(LocalTime.of(18, 0))) {
                            totalDays += 1.0;
                        } else if (endTime.toLocalTime().isAfter(LocalTime.of(12, 0))) {
                            totalDays += 0.5;
                        } else if (endTime.toLocalTime().isAfter(LocalTime.of(8, 0))) {
                            totalDays += 0.5;
                        }
                    }
                    break;
                }
            }

            // 移动到下一天
            current = current.toLocalDate().plusDays(1).atTime(8, 0);
        }

        return totalDays;
    }
}


